package financial.sharing.center.payable.service.impl;

import com.github.pagehelper.PageInfo;
import financial.sharing.center.common.enums.AccruedOperationStageEnum;
import financial.sharing.center.common.enums.BillOperationStageEnum;
import financial.sharing.center.common.enums.EnableStatusEnum;
import financial.sharing.center.common.enums.ResponseContext;
import financial.sharing.center.common.utils.BigDecimalUtil;
import financial.sharing.center.payable.dao.PayableBillMapper;
import financial.sharing.center.payable.model.entity.PayableAccrued;
import financial.sharing.center.payable.model.entity.PayableBill;
import financial.sharing.center.payable.service.PayableAccruedService;
import financial.sharing.center.payable.service.PayableBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName PayableBillServiceImpl
 * @Description TODO
 * @Author guoyuhang
 * @ @csdn https://blog.csdn.net/qq_40788718
 * @Date 2021/5/19
 * @Version 1.0
 */
@Service
public class PayableBillServiceImpl implements PayableBillService {

    @Autowired
    private PayableBillMapper payableBillMapper;

    @Autowired
    private PayableAccruedService payableAccruedServiceImpl;

    @Override
    public Integer getBillNumber(PayableAccrued payableAccrued) {
        Example example = new Example(PayableBill.class);
        example.createCriteria().andEqualTo("payableAccruedId",payableAccrued.getId())
                                .andEqualTo("enableStatusValue", EnableStatusEnum.正常.getValue());
        List<PayableBill> payableBillList = this.payableBillMapper.selectByExample(example);
        return payableBillList == null ? 0 : payableBillList.size();
    }

    @Override
    public PageInfo<PayableBill> getAllPayableBill(Integer contractId, Integer accruedId, Integer billId) {
        Example example = new Example(PayableBill.class);
        Example.Criteria criteria = example.createCriteria().andEqualTo("enableStatusValue", EnableStatusEnum.正常.getValue());
        if (contractId != null && contractId >= 0){
            criteria.andEqualTo("contractId", contractId);
        }
        if (accruedId != null && accruedId >= 0){
            criteria.andEqualTo("payableAccruedId", accruedId);
        }
        if (billId != null && billId >= 0){
            criteria.andEqualTo("id",billId);
        }
        List<PayableBill> payableBillList = this.payableBillMapper.selectByExample(example);
        for (PayableBill payableBill : payableBillList) {
            payableBill.setBillOperationStatusName(BillOperationStageEnum.int2Enum(payableBill.getBillOperationStatusValue()).getName());
        }
        return new PageInfo<>(payableBillList);
    }

    @Override
    public Integer createOnePayableBill(BigDecimal billAmount, String payableCompanyName, String receivableCompanyName) {
        PayableBill payableBill = new PayableBill(billAmount, payableCompanyName, receivableCompanyName);
        int i = this.payableBillMapper.insert(payableBill);
        return i == 1 ? ResponseContext.成功.getValue() : ResponseContext.创建失败.getValue();
    }

    @Override
    public Integer compileOnePayableBill(PayableBill payableBill) {
        if (BillOperationStageEnum.已确认.getValue().equals(payableBill.getBillOperationStatusValue())
                && payableBill.getPayableAccruedId() != null){
            PayableAccrued payableAccrued = this.payableAccruedServiceImpl.getPayableAccrued(payableBill.getPayableAccruedId());
            if (payableAccrued == null){
                return ResponseContext.计提不存在.getValue();
            }
            if (!AccruedOperationStageEnum.勾稽中.getValue().equals(payableAccrued.getAccruedOperationStageValue())){
                return ResponseContext.计提操作状态不符合.getValue();
            }
            if (EnableStatusEnum.正常.getValue().equals(payableAccrued.getEnableStatusValue())){
                payableBill.setContractId(payableAccrued.getContractId());
                payableAccrued.setTotalFeeAmount(payableAccrued.getTotalFeeAmount().add(payableBill.getBillAmount()));
                Integer flag = this.payableAccruedServiceImpl.compileOnePayableAccrued(payableAccrued);
                if (flag != ResponseContext.成功.getValue().intValue()){
                    return ResponseContext.更新失败.getValue();
                }
                payableBill.setBillOperationStatusValue(BillOperationStageEnum.已勾稽.getValue());
            }else{
                return ResponseContext.计提不存在.getValue();
            }
        }else if (BillOperationStageEnum.待确认.getValue().equals(payableBill.getBillOperationStatusValue())){
            payableBill.setBillOperationStatusValue(BillOperationStageEnum.已确认.getValue());
        }else {
            return ResponseContext.更新失败.getValue();
        }
        int i = this.payableBillMapper.updateByPrimaryKey(payableBill);
        return i == 1 ? ResponseContext.成功.getValue() : ResponseContext.更新失败.getValue();
    }

    @Override
    public Integer deleteOnePayableBill(Integer id) {
        PayableBill receivableBill = this.getPayableBill(id);
        receivableBill.setEnableStatusValue(EnableStatusEnum.弃用.getValue());
        if (BillOperationStageEnum.已勾稽.getValue().equals(receivableBill.getBillOperationStatusValue())){
            PayableAccrued payableAccrued = this.payableAccruedServiceImpl.getPayableAccrued(receivableBill.getPayableAccruedId());
            payableAccrued.setTotalFeeAmount(payableAccrued.getTotalFeeAmount().subtract(receivableBill.getBillAmount()));
            Integer flag = this.payableAccruedServiceImpl.compileOnePayableAccrued(payableAccrued);
            if (flag != ResponseContext.成功.getValue().intValue()){
                return ResponseContext.删除失败.getValue();
            }
        }
        int i = this.payableBillMapper.updateByPrimaryKey(receivableBill);

        return i == 1 ? ResponseContext.成功.getValue() : ResponseContext.删除失败.getValue();
    }

    @Override
    public PayableBill getPayableBill(Integer id) {
        return this.payableBillMapper.selectByPrimaryKey(id);
    }

    @Override
    public Map<Integer, BigDecimal> getMapPayableBill() {
        Example example = new Example(PayableBill.class);
        example.createCriteria().andEqualTo("enableStatusValue", EnableStatusEnum.正常.getValue())
                .andLessThanOrEqualTo("billOperationStatusValue", BillOperationStageEnum.已确认.getValue());
        List<PayableBill> payableBillList = this.payableBillMapper.selectByExample(example);
        Map<Integer,BigDecimal> result = new HashMap<>();
        for (PayableBill payableBill : payableBillList) {
            if (payableBill.getContractId() != null){
                if (result.get(payableBill.getContractId()) == null){
                    result.put(payableBill.getContractId(), BigDecimalUtil.ZERO);
                }
                result.put(payableBill.getContractId(), result.get(payableBill.getContractId()).add(payableBill.getBillAmount()));
            }
        }
        return result;
    }
}
